﻿using ICPFrameLib.Business;
using ICPFrameLib.Attributes;
using XHRPMIS.Common;
using EFFC.Frame.Net.Base.Common;
using EFFC.Frame.Net.Base.Data.Base;
using EFFC.Frame.Net.Module.Extend.EWRA.Attributes;
using EFFC.Frame.Net.Module.Extend.EWRA.Attributes.Validation;
using EFFC.Frame.Net.Unit.DB.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EFFC.Extends.LinqDLR2SQL;
using EFFC.Frame.Net.Unit.DB;
using EFFC.Frame.Net.Base.Data;
using System.IO;
using EFFC.Frame.Net.Base.Constants;
using System.Text.RegularExpressions;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System.Text;
using ICPFrameLib.Common;
using EFFC.Frame.Net.Unit.DB.Datas;

namespace XHRPMIS.Business.v1._0
{
    public partial class MetaDynamicForm
    {
        #region OpenAPI
        [EWRARoute("delete", "/md_form/{id}")]
        [EWRAEmptyValid("data")]
        [EWRARouteDesc("删除元数据表中的数据")]
        [EWRAAddInput("id", "string", "元数据表uid", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
        [EWRAAddInput("data", "array", @"待删除的数据，格式:['_default_pk值']", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
        [EWRAOutputDesc("返回结果", @"{
    code:'success-成功，failed-失败',
    msg:'提示信息'
    }")]
        public object Delete(string id)
        {
            var data = PostDataD.data;
            if (!(data is IEnumerable<object>))
            {
                return new
                {
                    code = "failed",
                    msg = "数据格式不正确"
                };
            }
            var datalist = (IEnumerable<object>)data;

            BeginTrans();
            var metaup = DB.NewMetaUnitParameter();
            var up = DB.NewDBUnitParameter();
            var rtn = DoDelete(metaup, up, id, datalist, BoolStd.IsNotBoolThen(Configs["Is_UseLocal"]));
            CommitTrans();
            return rtn;
        }
        [EWRARoute("delete", "/md_form/{id}/{pk}")]
        [EWRARouteDesc("删除元数据表中的单笔数据")]
        [EWRAAddInput("id", "string", "元数据表uid", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
        [EWRAAddInput("pk", "string", @"待删除的数据的_default_pk值", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
        [EWRAOutputDesc("返回结果", @"{
    code:'success-成功，failed-失败',
    msg:'提示信息'
    }")]
        public object Delete(string id, string pk)
        {
            var datalist = new List<object>();
            datalist.Add(pk);
            BeginTrans();
            var metaup = DB.NewMetaUnitParameter();
            var up = DB.NewDBUnitParameter();
            var rtn = DoDelete(metaup, up, id, datalist, BoolStd.IsNotBoolThen(Configs["Is_UseLocal"]));
            CommitTrans();
            return rtn;
        }
        #endregion

        #region LocalFunction
        public object DoDelete(UnitParameter metaup, UnitParameter up, string id, IEnumerable<object> data, bool is_use_local_upload = true)
        {
            var datalist = data.Select((d) => ComFunc.nvl(d)).ToList();
            var info = MetaDataUtilities.GetAllTables(metaup).Where(w => (w.MetaUID == id || w.MetaName == id) && w.IsCreated).FirstOrDefault();
            if (info == null)
            {
                return new
                {
                    code = "failed",
                    msg = "元数据表不存在",
                };
            }
            string tablename = info.MetaName;
            //查看当前资料是否已经完成或终止
            var pks = string.Join(",", datalist);
            var exists = from t in DB.LamdaTable(up, tablename, "a")
                         where t._default_pk.within(pks)
                         select t;
            var existlist = exists.GetQueryList(up);
            if (existlist.Where(w => IntStd.IsNotIntThen(w._lock) == MetaLock.Lock
            || IntStd.IsNotIntThen(w._lock) == MetaLock.LockDelete
            || IntStd.IsNotIntThen(w._lock) == MetaLock.LockUpdateDelete).Count() > 0)
            {
                return new
                {
                    code = "failed",
                    msg = "存在已锁定的资料，不可继续操作",
                };
            }

            var subs = MetaDataUtilities.GetAllTables(metaup).Where(w => w.MetaMainUID == info.MetaUID && w.IsCreated);
            var subresult = FrameDLRObject.CreateInstance(DoDeleteSubs(metaup, up, info.MetaUID, datalist, is_use_local_upload));
            if (subresult.code != "success")
            {
                return new
                {
                    code = "failed",
                    msg = $"子表数据删除失败-{subresult.msg}"
                };
            }
            //找出文件图片等栏位
            var columnlist = info.columns;
            string[] filecolumns = columnlist.Where(w => new string[] { "file", "picture" }.Contains((string)w.MetaDataType)).Select(d => d.MetaColumnName).ToArray();
            string[] multifilecolumns = columnlist.Where(w => new string[] { "multi-file", "pictures" }.Contains((string)w.MetaDataType)).Select(d => d.MetaColumnName).ToArray();

            foreach (var item in existlist)
            {
                var delfilepath = new List<string>();
                foreach (var c in filecolumns)
                {
                    var v = ComFunc.nvl(item.GetValue(c));
                    if (v != "") delfilepath.Add(v);
                }
                foreach (var c in multifilecolumns)
                {
                    var v = FrameDLRObject.IsJsonArrayThen(ComFunc.nvl(item.GetValue(c)), new object[] { });
                    if (v != null) delfilepath.AddRange(v.Select(d => ComFunc.nvl(d)));
                }
                FileHelper.DelUploadFiles(delfilepath.ToArray());

                DB.QuickDelete(up, tablename, new
                {
                    _default_pk = item.GetValue("_default_pk")
                });
            }
            return new
            {
                code = "success",
                msg = "操作成功",
            };
        }
        /// <summary>
        /// 删除子表资料
        /// </summary>
        /// <param name="metaup"></param>
        /// <param name="up"></param>
        /// <param name="main_id">主表MetaUID</param>
        /// <param name="main_data">主表资料的PK列表</param>
        /// <param name="is_use_local_upload"></param>
        /// <returns></returns>
        public object DoDeleteSubs(UnitParameter metaup, UnitParameter up, string main_id, IEnumerable<object> main_data, bool is_use_local_upload = true)
        {
            if (main_data.Count() <= 0)
            {
                return new
                {
                    code = "success",
                    msg = ""
                };
            }

            var datalist = main_data.Select((d) => ComFunc.nvl(d)).ToList();
            var s = from t in DB.LamdaTable(metaup, "EXTEND_METADATA", "a")
                    where t.MetaMainUID == main_id && t.IsCreated == 1
                    select t;
            var list = MetaDataUtilities.GetAllTables(metaup).Where(w => w.MetaMainUID == main_id && w.IsCreated).ToList();
            if (list.Count <= 0)
            {
                return new
                {
                    code = "success",
                    msg = "元数据表不存在,无须操作"
                };
            }
            var main_pk = string.Join(",", datalist);
            foreach (var sub in list)
            {
                string tablename = sub.MetaName;
                //查看当前资料是否已经完成或终止
                var exists = from t in DB.LamdaTable(up, tablename, "a")
                             where t._default_ref.within(main_pk)
                             select t;
                var existlist = exists.GetQueryList(up);
                if (existlist.Count() <= 0)
                {
                    continue;
                }
                if (existlist.Where(w => IntStd.IsNotIntThen(w._lock) == MetaLock.Lock
                || IntStd.IsNotIntThen(w._lock) == MetaLock.LockDelete
                || IntStd.IsNotIntThen(w._lock) == MetaLock.LockUpdateDelete).Count() > 0)
                {
                    return new
                    {
                        code = "failed",
                        msg = "存在已锁定的资料，不可继续操作",
                    };
                }
                var pklist = existlist.Select(d => (string)ComFunc.nvl(d.GetValue("_default_pk"))).ToList();
                //递归删除子表资料
                dynamic subresult = DoDeleteSubs(metaup, up, sub.MetaUID, pklist, is_use_local_upload);
                if (subresult.code != "success")
                {
                    return new
                    {
                        code = "failed",
                        msg = $"子表数据删除失败-{subresult.msg}"
                    };
                }
                //找出文件图片等栏位
                var columnlist = sub.columns;
                string[] filecolumns = columnlist.Where(w => new string[] { "file", "picture" }.Contains((string)w.MetaDataType)).Select(d => d.MetaColumnName).ToArray();
                string[] multifilecolumns = columnlist.Where(w => new string[] { "multi-file", "pictures" }.Contains((string)w.MetaDataType)).Select(d => d.MetaColumnName).ToArray();

                foreach (var item in existlist)
                {
                    var delfilepath = new List<string>();
                    foreach (var c in filecolumns)
                    {
                        var v = ComFunc.nvl(item.GetValue(c));
                        if (v != "") delfilepath.Add(v);
                    }
                    foreach (var c in multifilecolumns)
                    {
                        var v = FrameDLRObject.IsJsonArrayThen(ComFunc.nvl(item.GetValue(c)), new object[] { }).Select(d => ComFunc.nvl(d)).ToList();
                        if (v != null) delfilepath.AddRange(v);
                    }
                    FileHelper.DelUploadFiles(delfilepath.ToArray());

                    DB.QuickDelete(up, tablename, new
                    {
                        _default_pk = item.GetValue("_default_pk")
                    });
                }
            }

            return new
            {
                code = "success",
                msg = "操作成功",
            };
        }
        #endregion
    }
}
